package com.dc.commons.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import com.dc.commons.helper.DateHelper;
import com.dc.commons.persistence.embeddable.Attachment;
import com.dc.commons.query.DcQuery;
import com.dc.commons.query.ExcelQueryPageService;
import com.dc.commons.sys.persistence.IAttachment;
import com.dc.commons.utils.Excel.Exportor;
import com.dc.commons.utils.Excel.Exportor.ExcelType;
import com.dc.commons.utils.excel.ExcelCovert;
import com.dc.commons.utils.excel.ExportFormat;
import com.dc.commons.utils.excel.PipeLine;
import com.google.common.collect.Lists;

/*******************************************************************************<P>
 * 文件名: ExcelExportor.java <br>
 * 版本: 1.0<br>
 * 描述:<br>
 * 版权所有: <br>
 * <P>
 * 创建者: 王建栋 <br>
 * 创建日期: 2016年6月7日 下午12:44:41<br>
 * 修改者: <br>
 * 修改日期: <br>
 * 修改说明: <br>
 ******************************************************************************/
public class ExcelExportor {
	
		/**
		 * 根据业务导出
		 * @param queryPageService 分页查询Service
		 * @param dcQuery			查询数据
		 */
		public static <T>IAttachment export(final ExcelQueryPageService<T> queryPageService,final DcQuery dcQuery){
			String realPath=dcQuery.getRealPath();
			Class<T> clazz=Reflections.getClassGenricType(queryPageService.getClass());
			String type=clazz.getSimpleName();
			String filePath="/upload/"+type+"/"+DateHelper.formatDate().replace("-", "/")+"/"+UUID.randomUUID().toString()+".xls";
			Attachment attachment=new Attachment();
			try{
				File file=new File(realPath,filePath);
				if(!file.getParentFile().exists()){
					file.getParentFile().mkdirs();
				}
				export(queryPageService, dcQuery, new FileOutputStream(file),ExcelType.getExcelType(file));
				attachment.setName(file.getName());
				attachment.setLink(filePath);
				attachment.setType(type);
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				
			}
			return attachment;
		}
		
		/**
		 * 根据业务导出
		 * @param queryPageService 分页查询Service
		 * @param dcQuery			查询数据
		 * @param out				输出流
		 * @param excelType			Excel类型
		 */
		public static <T>void export(final ExcelQueryPageService<T> queryPageService,final DcQuery dcQuery,OutputStream out,ExcelType excelType){
			Class<T> clazz=Reflections.getClassGenricType(queryPageService.getClass());
			List<ExportFormat<T>> configList=getExportFormatList(dcQuery.getExceltMap(), clazz);
			export(queryPageService, dcQuery, configList, out,excelType);
		}
		
		/**
		 * 根据业务导出
		 * @param queryPageService	分页查询Service
		 * @param dcQuery			查询数据
		 * @param configList		导出配置列表
		 * @param out				输出流
		 * @param excelType			Excel类型
		 */
		public static <T>void export(final ExcelQueryPageService<T> queryPageService,final DcQuery dcQuery,final List<ExportFormat<T>> configList,OutputStream out,ExcelType excelType){
			
			List<String> titles=Lists.newArrayList();
			for(ExportFormat<T> config:configList){
				titles.add(config.getTitle());
			}
			final int max=65535;
			dcQuery.setPageable(new PageRequest(0, max));
			
			Exportor.export(titles, new PipeLine(){

				@Override
				public List<List<Object>> findList() {
					
					// 通过设置 end 跳出循环，避免做一个无用的查询
					if(dcQuery.isEnd()){
						return null;
					}
					
					Page<T> page=queryPageService.queryPage(dcQuery);
					
					List<List<Object>> result=Lists.newArrayList();
					
					for(T t:page.getContent()){
						List<Object> record=Lists.newArrayList();
						for(ExportFormat<T> config:configList){
							record.add(config.formatValue(t));
						}
						result.add(record);
					}
					
					
					// 翻到最后一页的时候 设置 PageSize=0 准备跳出循环，否则进行下一页的查询
					int pageNo=dcQuery.getPageable().getPageNumber();
					pageNo++;
					if(page.getTotalPages()<=pageNo){
						dcQuery.setEnd(true);
					}else{
						dcQuery.setPageable(new PageRequest(pageNo, max));
					}
					
					return result.size()>0?result:null;
				}
				
			}, out,excelType);
		}
		
		/**
		 *  配置的 格式为 <br>
		 *  	key=序号_代码
		 *  	value=名称
		 * @param map
		 * @param clazz
		 * @return ExportFormatList
		 */
		private static  <T>List<ExportFormat<T>> getExportFormatList(Map<String, String> map,Class<T> clazz){
			List<ExportFormat<T>> list=Lists.newArrayList();
			List<String> keys=Lists.newArrayList();
			for(String key:map.keySet()){
				keys.add(key);
			}
			Collections.sort(keys);
			
			for(final String key:keys){
				final Object value=map.get(key);
				final String field=key.substring(key.indexOf("_")+1);
				if(value!=null&&StringUtils.isNotEmpty(value.toString())){
					list.add(new ExcelCovert.DefaultExportFormat<T>(value.toString(), field));
				}
			}
			
			return list;
		}
		
		
}
